﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Orange.Lib.Effective
{
    namespace EqualityUse
    {
        /// <summary>
        /// Demonstrate customerize referenceType equal.
        /// </summary>
        class Orange : IEquatable<Orange>
        {
            public string Color { get; private set; }
            public int Size { get; private set; }

            public override bool Equals(object obj)
            {
                if (object.ReferenceEquals(obj, null))
                {
                    return false;
                }
                //Reference Equal: judge object identify
                if (object.ReferenceEquals(this, obj))
                {
                    return true;
                }
                if (this.GetType() != obj.GetType())
                {
                    return false;
                }

                return this.Equals(obj as Orange);
            }

            //Method GetHashCode should be consist with Equal.
            public override int GetHashCode()
            {
                return this.Color.GetHashCode() +
                    this.Size.GetHashCode();
            }

            //implement IEquatable<T> interface's Equals method
            public bool Equals(Orange other)
            {
                return this.Color == other.Color && this.Size == other.Size;
            }
        }

        /// <summary>
        /// Demonstrate customerize valueType equal.
        /// </summary>
        struct Cheng : IEquatable<Cheng>
        {
            int i;
            int j;

            public override bool Equals(object obj)
            {
                if (this.GetType() != obj.GetType())
                {
                    return false;
                }
                else
                {
                    return this.Equals((Orange)obj);
                }
            }

            public bool Equals(Cheng other)
            {
                return this.i == other.i
                    && this.j == other.j;
            }

            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }

        class MyClass<T> where T : new()
        {
            public T GetItem()
            {
                Type a = typeof(T);
                return new T();
            }
        }
    }
}
